package de.lulusoft.anothertorrent.gui.views;

import java.util.ArrayList;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;

import de.lulusoft.anothertorrent.core.rtorrent.File;
import de.lulusoft.anothertorrent.core.rtorrent.Peer;
import de.lulusoft.anothertorrent.core.rtorrent.Torrent;
import de.lulusoft.anothertorrent.core.rtorrent.Tracker;
import de.lulusoft.anothertorrent.gui.AnotherTorrentGui;
import de.lulusoft.anothertorrent.gui.preferences.PreferenceConstants;
import de.lulusoft.anothertorrent.gui.util.Util;
import de.lulusoft.anothertorrent.gui.views.Providers.FilesTableContentProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.FilesTableLabelProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.PeersTableContentProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.PeersTableLabelProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.TableColumnSorter;
import de.lulusoft.anothertorrent.gui.views.Providers.TorrentDetailsViewInput;
import de.lulusoft.anothertorrent.gui.views.Providers.TrackerTableContentProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.TrackerTableLabelProvider;

public class TorrentDetailsView extends ViewPart {
	
	public static final String ID = "de.lulusoft.anothertorrent.gui.views.TorrentDetailsView";
	
	private Job timer = null;
	private TorrentDetailsViewInput m_input = null;
	private ArrayList<Peer> m_peers = null;
	private ArrayList<File> m_files = null;
	private ArrayList<Tracker> m_tracker = null;
	
	
	// Main Widgets
	private TabFolder tabs = null;
		
	// Info Widgets
	private Text infoName = null;
	private Text infoUpRate = null;
	private Text infoDownRate = null;
	private Text infoPeers = null;
	private Text infoSize = null;
	private Text infoPath = null;
	
	
	// Files Widgets
	private TableViewer tableFiles = null;
	private static final String[] fileProperties = {"Filename", "Size", "Done", "Chunks", "Priority"}; 
		
	// Peers Widgets
	private TableViewer tablePeers = null;
	private static final String[] peersProperties = {"Address", "Client", "Complete", "Download", "Upload", "Peer"};
	
	// Tracker Widgets
	private TableViewer tableTracker = null;
	private static final String[] trackerProperties = {"URL", "Last", "Interval", "Scraped", "Enabled"}; 
	
	public TorrentDetailsView() {
	}
	
	@Override
	public void dispose() {
		timer.cancel();
		super.dispose();
	}

	public void setInput(Object input)
	{
		if (input instanceof TorrentDetailsViewInput)
		{
			timer.cancel();
			
			m_input = (TorrentDetailsViewInput) input;
			this.setPartName(m_input.getTorrent().getName());
			
			// Display info
			updateInfoTab(m_input.getTorrent());
			
			// Get Files
			tableFiles.setInput(m_input.getServer().getRTorrentManager().getFiles(m_input.getTorrent().getHash()));
			for (TableColumn tc : tableFiles.getTable().getColumns())
				tc.pack();
			
			// Get Peers
			tablePeers.setInput(m_input.getServer().getRTorrentManager().getPeers(m_input.getTorrent().getHash()));
			for (TableColumn tc : tablePeers.getTable().getColumns())
				tc.pack();
			
			// Get Trackers
			tableTracker.setInput(m_input.getServer().getRTorrentManager().getTrackers(m_input.getTorrent().getHash()));
			for (TableColumn tc : tableTracker.getTable().getColumns())
				tc.pack();
			
			timer.schedule(AnotherTorrentGui.getDefault()
					.getPreferenceStore().getInt(PreferenceConstants.P_UPDATE_INTERVAL_DETAILS_VIEW) * 1000);
			
		}
		
	}
	
	public void updateInfoTab(Torrent t)
	{
		infoName.setText(t.getBase_filename());
		infoUpRate.setText(Util.formatBytes(t.getUp_rate()));
		infoDownRate.setText(Util.formatBytes(t.getDown_rate()));
		infoPeers.setText(t.getPeers_connected() + " / " + t.getPeers_not_connected() + " / " + t.getPeers_complete() + " / " + t.getPeers_accounted());
		infoSize.setText(Util.formatBytes(t.getSize_bytes()));
		infoPath.setText(t.getBase_path());
	}

	@Override
	public void createPartControl(Composite parent) {
		
		// Create TabFolders
		tabs = new TabFolder(parent, SWT.BORDER);
		TabItem main = new TabItem (tabs, SWT.NONE);
		main.setText("Info");
		TabItem files = new TabItem (tabs, SWT.NONE);
		files.setText("Files");
		TabItem peers = new TabItem (tabs, SWT.NONE);
		peers.setText("Peers");
		TabItem trackers = new TabItem (tabs, SWT.NONE);
		trackers.setText("Tracker");
		
		
		// Create Tab Contents
		files.setControl(createFilesTab(tabs));
		peers.setControl(createPeersTab(tabs));
		trackers.setControl(createTrackerTab(tabs));
		main.setControl(createInfoTab(tabs));
		
		// create timer
		timer = new Job("Update Torrent Details Data"){
		
			@Override
			protected IStatus run(IProgressMonitor monitor) {

				monitor.beginTask("Updating Torrent Details Data", IProgressMonitor.UNKNOWN);
				m_files = m_input.getServer().getRTorrentManager().getFiles(m_input.getTorrent().getHash());
				m_peers = m_input.getServer().getRTorrentManager().getPeers(m_input.getTorrent().getHash());
				m_tracker = m_input.getServer().getRTorrentManager().getTrackers(m_input.getTorrent().getHash());
				m_input.getServer().getRTorrentManager().updateTorrent(m_input.getTorrent());
				
				UIJob ui = new UIJob(Display.getDefault(), "Update Torrent Details") {
					@Override
					public IStatus runInUIThread(IProgressMonitor monitor) {
						monitor.beginTask("Updating Torrent " + m_input.getTorrent().getName(), IProgressMonitor.UNKNOWN);
						tableFiles.setInput(m_files);
						tablePeers.setInput(m_peers);
						tableTracker.setInput(m_tracker);
						updateInfoTab(m_input.getTorrent());
						monitor.done();
						return null;
					}
				};
				ui.setUser(false);
				ui.schedule();
				timer.schedule(AnotherTorrentGui.getDefault()
						.getPreferenceStore().getInt(PreferenceConstants.P_UPDATE_INTERVAL_DETAILS_VIEW) * 1000);
				monitor.done();
				return null;
			}
		};
		timer.setUser(false);
		
		
		
	}

	private Composite createInfoTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new GridLayout(2, false));
		GridData gd = new GridData();
		gd.grabExcessHorizontalSpace = true;
		gd.grabExcessVerticalSpace = false;
		gd.verticalAlignment = SWT.FILL;
		gd.horizontalAlignment = SWT.FILL;
		
		Label  lInfoName = new Label(main, SWT.NONE);
		lInfoName.setLayoutData(gd);
		lInfoName.setText("Name: ");
		infoName = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoName.setLayoutData(gd);
		
		Label  linfoPath = new Label(main, SWT.NONE);
		linfoPath.setLayoutData(gd);
		linfoPath.setText("Path: ");
		infoPath = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoPath.setLayoutData(gd);
		
		Label  linfoSize = new Label(main, SWT.NONE);
		linfoSize.setLayoutData(gd);
		linfoSize.setText("Size: ");
		infoSize = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoSize.setLayoutData(gd);
		
		Label  linfoDownRate = new Label(main, SWT.NONE);
		linfoDownRate.setLayoutData(gd);
		linfoDownRate.setText("DownRate: ");
		infoDownRate = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoDownRate.setLayoutData(gd);
		
		Label  linfoUpRate = new Label(main, SWT.NONE);
		linfoUpRate.setLayoutData(gd);
		linfoUpRate.setText("UpRate: ");
		infoUpRate = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoUpRate.setLayoutData(gd);
		
		Label  linfoPeers = new Label(main, SWT.NONE);
		linfoPeers.setLayoutData(gd);
		linfoPeers.setText("Peers (Connected/NotCon/Complete/Accounted): ");
		infoPeers = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoPeers.setLayoutData(gd);
		
		return main;
	}
	
	private Composite createFilesTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new FillLayout());
		tableFiles = new TableViewer(main, SWT.FULL_SELECTION);
		tableFiles.getTable().setHeaderVisible(true);
		tableFiles.getTable().setLinesVisible(true);
		
		int i = 0;
		for (final String prop : fileProperties)
		{
			final int colIdx = i;
			TableViewerColumn column = new TableViewerColumn(tableFiles, SWT.NONE);
			column.getColumn().setText(prop);
			column.getColumn().setWidth(100);
			column.getColumn().setMoveable(true);

			TableColumnSorter cSorter = new TableColumnSorter(tableFiles, column.getColumn()) 
			{
			     protected int doCompare(Viewer v, Object e1, Object e2) 
			     {
			    	 File t1 = (File)e1;
			    	 File t2 = (File)e2;
			    	 if (prop.equals("Size"))
			    	 {
			    		return t1.getSize_bytes().compareTo(t2.getSize_bytes()); 
			    	 }
			    	 else if (prop.equals("Done"))
			    	 {
			    		return t1.getDonePercent().compareTo(t2.getDonePercent()); 
			    	 }
			      	 else if (prop.equals("Priority"))
			    	 {
			    		return t1.getPriority().compareTo(t2.getPriority()); 
			    	 }
			    	 else
			    	 {
			             ITableLabelProvider lp = ((ITableLabelProvider) tableFiles
			            		 .getLabelProvider());
			             String s1 = lp.getColumnText(e1, colIdx);
			             String s2 = lp.getColumnText(e2, colIdx);
			             return s1.compareTo(s2);
			    	 }
			     }
			};

			cSorter.setSorter(cSorter, TableColumnSorter.ASC);
			i++;
		}
		
		tableFiles.setContentProvider(new FilesTableContentProvider());
		tableFiles.setLabelProvider(new FilesTableLabelProvider());
		
		return main;
	}
	
	private Composite createPeersTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new FillLayout());
		tablePeers = new TableViewer(main, SWT.FULL_SELECTION);
		tablePeers.getTable().setHeaderVisible(true);
		tablePeers.getTable().setLinesVisible(true);
		
		int i = 0;
		for (final String prop : peersProperties)
		{
			final int colIdx = i;
			TableViewerColumn column = new TableViewerColumn(tablePeers, SWT.NONE);
			column.getColumn().setText(prop);
			column.getColumn().setWidth(100);
			column.getColumn().setMoveable(true);

			TableColumnSorter cSorter = new TableColumnSorter(tablePeers, column.getColumn()) 
			{
			     protected int doCompare(Viewer v, Object e1, Object e2) 
			     {
			    	 Peer t1 = (Peer)e1;
			    	 Peer t2 = (Peer)e2;
			    	 if (prop.equals("Complete"))
			    	 {
			    		return t1.getCompleted_percent().compareTo(t2.getCompleted_percent()); 
			    	 }
			    	 else if (prop.equals("Download"))
			    	 {
			    		return t1.getDown_rate().compareTo(t2.getDown_rate()); 
			    	 }
			      	 else if (prop.equals("Upload"))
			    	 {
			    		return t1.getUp_rate().compareTo(t2.getUp_rate()); 
			    	 }
			    	 else
			    	 {
			             ITableLabelProvider lp = ((ITableLabelProvider) tablePeers
			            		 .getLabelProvider());
			             String s1 = lp.getColumnText(e1, colIdx);
			             String s2 = lp.getColumnText(e2, colIdx);
			             return s1.compareTo(s2);
			    	 }
			     }
			};

			cSorter.setSorter(cSorter, TableColumnSorter.ASC);
			i++;
		}
		
		tablePeers.setContentProvider(new PeersTableContentProvider());
		tablePeers.setLabelProvider(new PeersTableLabelProvider());
		
		
		return main;
	}
	
	private Composite createTrackerTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new FillLayout());
		tableTracker = new TableViewer(main, SWT.FULL_SELECTION);
		tableTracker.getTable().setHeaderVisible(true);
		tableTracker.getTable().setLinesVisible(true);
		
		int i = 0;
		for (final String prop : trackerProperties)
		{
			final int colIdx = i;
			TableViewerColumn column = new TableViewerColumn(tableTracker, SWT.NONE);
			column.getColumn().setText(prop);
			column.getColumn().setWidth(100);
			column.getColumn().setMoveable(true);

			TableColumnSorter cSorter = new TableColumnSorter(tableTracker, column.getColumn()) 
			{
			     protected int doCompare(Viewer v, Object e1, Object e2) 
			     {
//			    	 Tracker t1 = (Tracker)e1;
//			    	 Tracker t2 = (Tracker)e2;
			    	
		             ITableLabelProvider lp = ((ITableLabelProvider) tableTracker
		            		 .getLabelProvider());
		             String s1 = lp.getColumnText(e1, colIdx);
		             String s2 = lp.getColumnText(e2, colIdx);
		             return s1.compareTo(s2);
			     }
			};

			cSorter.setSorter(cSorter, TableColumnSorter.ASC);
			i++;
		}
		
		tableTracker.setContentProvider(new TrackerTableContentProvider());
		tableTracker.setLabelProvider(new TrackerTableLabelProvider());
		
		
		return main;
	}
	

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}
